export function debounce (func, wait, immediate) {
    let timeout, args, context, timestamp, result

    const later = function () {
        // 据上一次触发时间间隔
        const last = +new Date() - timestamp

        // 上次被包装函数被调用时间间隔last小于设定时间间隔wait
        if (last < wait && last > 0) {
            timeout = setTimeout(later, wait - last)
        } else {
            timeout = null
            // 如果设定为immediate===true，因为开始边界已经调用过了此处无需调用
            if (!immediate) {
                result = func.apply(context, args)
                if (!timeout) context = args = null
            }
        }
    }

    return function (...args) {
        context = this
        timestamp = +new Date()
        const callNow = immediate && !timeout
        // 如果延时不存在，重新设定延时
        if (!timeout) timeout = setTimeout(later, wait)
        if (callNow) {
            result = func.apply(context, args)
            context = args = null
        }

        return result
    }
}

// 获取sessionStorage
export function getStorage (name) {
    const temp = JSON.parse(sessionStorage.getItem(name));
    if (temp && temp != undefined) {
        return temp
    }
    return false
}

// 设置sessionStorage
export function setStorage (name, data) {
    const temp = JSON.stringify(data);
    return sessionStorage.setItem(name, temp);
}

// 清除对象中属性值为""的属性
export function filterParams (obj) { // 剔除对象的空属性
    const _newObj = {};
    for (const key in obj) {
        if (obj.hasOwnProperty(key)) { // 判断对象中是否有这个属性
            if (isEmpty(obj[key])) continue;
            _newObj[key] = typeof obj[key] === 'object' ? (
                obj[key] instanceof Array ? ArrayFilterParams(obj[key]) : filterParams(obj[key])
            ) : obj[key];
        }
    }
    return _newObj;
}
function ArrayFilterParams (arr) { // 剔除数组中的空值
    const err = [];
    const empty_arr = ['', undefined, null];
    arr.forEach((item, index) => {
        if (isEmpty(item)) return;
        err.push(
            typeof item === 'object' ? (
                item instanceof Array ? ArrayFilterParams(item) : filterParams(item)
            ) : item
        );
    })
    return err;
}
function isEmpty (obj) { // 为空情况
    const empty_arr = ['', undefined, null];
    return (empty_arr.indexOf(obj) > -1 || obj.toString().trim() === '');
}

export function addition (arg1, arg2) { // 加法
    var r1, r2, m;
    try {
        r1 = arg1.toString().split('.')[1].length;
    } catch (e) {
        r1 = 0;
    }
    try {
        r2 = arg2.toString().split('.')[1].length;
    } catch (e) {
        r2 = 0;
    }
    m = Math.pow(10, Math.max(r1, r2));
    return (arg1 * m + arg2 * m) / m;
}

export function subtraction (arg1, arg2) { // 减法
    var r1, r2, m, n;
    try {
        r1 = arg1.toString().split('.')[1].length;
    } catch (e) {
        r1 = 0;
    }
    try {
        r2 = arg2.toString().split('.')[1].length;
    } catch (e) {
        r2 = 0;
    }
    m = Math.pow(10, Math.max(r1, r2));
    // 动态控制精度长度
    n = (r1 >= r2) ? r1 : r2;
    return ((arg1 * m - arg2 * m) / m).toFixed(n);
}

export function accMul (arg1, arg2) { // 乘法
    var m = 0;
    var s1 = arg1.toString();
    var s2 = arg2.toString();
    try {
        m += s1.split('.')[1].length;
    } catch (e) {
    }
    try {
        m += s2.split('.')[1].length;
    } catch (e) {
    }
    return Number(s1.replace('.', '')) * Number(s2.replace('.', '')) / Math.pow(10, m);
}

export function division (arg1, arg2) { // 除法
    var t1 = 0;
    var t2 = 0;
    var r1;
    var r2;
    try {
        t1 = arg1.toString().split('.')[1].length;
    } catch (e) {
    }
    try {
        t2 = arg2.toString().split('.')[1].length;
    } catch (e) {
    }
    r1 = Number(arg1.toString().replace('.', ''));
    r2 = Number(arg2.toString().replace('.', ''));
    return ((r1 / r2) * Math.pow(10, t2 - t1)).toFixed(4)
}

export function deepClone (target) {
    // 定义一个变量
    let result
    // 如果当前需要深拷贝的是一个对象的话
    if (typeof target === 'object') {
        // 如果是一个数组的话
        if (Array.isArray(target)) {
            result = [] // 将result赋值为一个数组，并且执行遍历
            for (const i in target) {
                // 递归克隆数组中的每一项
                result.push(deepClone(target[i]))
            }
            // 判断如果当前的值是null的话；直接赋值为null
        } else if (target === null) {
            result = null
            // 判断如果当前的值是一个RegExp对象的话，直接赋值
        } else if (target.constructor === RegExp) {
            result = target
        } else {
            // 否则是普通对象，直接for in循环，递归赋值对象的所有值
            result = {}
            for (const i in target) {
                result[i] = deepClone(target[i])
            }
        }
        // 如果不是对象的话，就是基本数据类型，那么直接赋值
    } else {
        result = target
    }
    // 返回最终结果
    return result
}
